// FacebookHyperLink.cs
// Facebook/FrameworkWeb/Web/IFrame
// Copyright (c) 2007, Nikhil Kothari. All Rights Reserved.
//

using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Facebook.Web;

namespace Facebook.Web.IFrame {

    /// <summary>
    /// A hyperlink control for IFrame Facebook applications to render anchors
    /// to other IFrame pages within the application such that pages are
    /// navigated appropriately within the Facebook environment so as to
    /// preserve user session information as well as enable bookmarkability
    /// of application pages.
    /// </summary>
    [
    DefaultProperty("NavigateUrl"),
    Designer(typeof(Facebook.Design.Web.IFrame.FacebookHyperLinkDesigner), typeof(IDesigner)),
    PersistChildren(false),
    ParseChildren(true)
    ]
    public class FacebookHyperLink : WebControl {

        /// <summary>
        /// Initializes a FacebookHyperLink control.
        /// </summary>
        public FacebookHyperLink()
            : base(HtmlTextWriterTag.A) {
        }

        /// <summary>
        /// Gets or sets the image to display within the hyperlink.
        /// </summary>
        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(""),
        Description("The image to display within the hyperlink."),
        Editor(typeof(System.Web.UI.Design.ImageUrlEditor), typeof(System.Drawing.Design.UITypeEditor)),
        UrlProperty()
        ]
        public virtual string ImageUrl {
            get {
                string s = (string)ViewState["ImageUrl"];
                return((s == null) ? String.Empty : s);
            }
            set {
                ViewState["ImageUrl"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the URL to navigate to.
        /// </summary>
        [
        Bindable(true),
        Category("Navigation"),
        DefaultValue(""),
        Description("The URL to navigate to."),
        Editor(typeof(System.Web.UI.Design.UrlEditor), typeof(System.Drawing.Design.UITypeEditor)),
        UrlProperty()
        ]
        public string NavigateUrl {
            get {
                string s = (string)ViewState["NavigateUrl"];
                return((s == null) ? String.Empty : s);
            }
            set {
                ViewState["NavigateUrl"] = value;
            }
        }

        /// <summary>
        /// Gets or sets the text to display within the hyperlink (or the alternate text
        /// if an image is displayed instead).
        /// </summary>
        [
        Bindable(true),
        Category("Appearance"),
        DefaultValue(""),
        Description("The text to display within the hyperlink.")
        ]
        public virtual string Text {
            get {
                object o = ViewState["Text"];
                return ((o == null) ? String.Empty : (string)o);
            }
            set {
                ViewState["Text"] = value;
            }
        }

        /// <internalonly/>
        protected override void AddAttributesToRender(HtmlTextWriter writer) {
            if (Enabled && !IsEnabled) {
                // We need to do the cascade effect on the server, because the browser
                // only renders as disabled, but doesn't disable the functionality.
                writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled");
            }

            base.AddAttributesToRender(writer);

            string s = NavigateUrl;
            if ((s.Length > 0) && IsEnabled) {
                string resolvedUrl = ResolveClientUrl(s);

                FacebookApplication app = FacebookApplication.GetCurrent(Page);
                if ((DesignMode == false) && app.InIFramePage && app.IsSessionCreated) {
                    Debug.Assert(app.Session is FacebookIFrameSession);
                    resolvedUrl = ((FacebookIFrameSession)app.Session).ResolveUrl(Context, resolvedUrl);

                    writer.AddAttribute(HtmlTextWriterAttribute.Target, "_top");
                }

                writer.AddAttribute(HtmlTextWriterAttribute.Href, resolvedUrl);
            }
        }

        /// <internalonly/>
        protected override void OnPreRender(EventArgs e) {
            base.OnPreRender(e);

            if (DesignMode) {
                return;
            }

            FacebookApplication app = FacebookApplication.GetCurrent(Page);
            if (app == null) {
                throw new InvalidOperationException("You must add a FacebookApplication control to this page to use the FacebookHyperLink control.");
            }
            if (app.Mode != FacebookApplicationMode.IFrame) {
                throw new InvalidOperationException("You must set the Mode property on the FacebookApplication to IFrame to use the FacebookHyperLink control.");
            }
        }

        /// <internalonly/>
        protected override void RenderContents(HtmlTextWriter writer) {
            string text = Text;
            string image = ImageUrl;
            if (image.Length > 0) {
                image = ResolveClientUrl(image);

                writer.AddAttribute(HtmlTextWriterAttribute.Src, image);
                writer.AddAttribute(HtmlTextWriterAttribute.Border, "0");
                if (text.Length != 0) {
                    writer.AddAttribute(HtmlTextWriterAttribute.Title, text);
                    writer.AddAttribute(HtmlTextWriterAttribute.Alt, text);
                }
                writer.RenderBeginTag(HtmlTextWriterTag.Img);
                writer.RenderEndTag();
            }
            else {
                writer.Write(text);
            }
        }
    }
}
